#include "ctagmobitordlg.h"
#include "ui_ctagmobitordlg.h"
#include "cpublicdata.h"
#include "cglobal.h"

CTagMobitorDlg::CTagMobitorDlg(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::CTagMobitorDlg)
{
    ui->setupUi(this);
    m_nCurrentPage = 1;
    m_nPageSize = 100;
    m_nTotalPages = 0;
    m_pModel=nullptr;
    initConnect();
    initUi();
    setFilter(ui->lineEditFilter->text());
    m_pTimer = new QTimer();
    connect(m_pTimer, &QTimer::timeout, this, &CTagMobitorDlg::slotDataFlush);
    m_pTimer->start(1000);//默认1秒刷新一次
    updateButtonStates();
}

CTagMobitorDlg::~CTagMobitorDlg()
{
    m_pTimer->stop();
    m_pTimer->deleteLater();
    delete ui;
}

void CTagMobitorDlg::initConnect()
{
    connect(ui->pushButtonJump, &QPushButton::clicked, this, &CTagMobitorDlg::slotPushButtonJump);
    connect(ui->pushButtonNext, &QPushButton::clicked, this, &CTagMobitorDlg::slotPushButtonNext);
    connect(ui->pushButtonPre, &QPushButton::clicked, this, &CTagMobitorDlg::slotPushButtonPre);
    connect(ui->pushButtonFilter, &QPushButton::clicked, this, &CTagMobitorDlg::slotPushButtonFilter);
    connect(ui->comboBoxPageSize, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotComboBoxPageSizeChanged(const QString&)));
}

void CTagMobitorDlg::initUi()
{
    this->setWindowTitle(A2T("测点监视"));
    ui->comboBoxPageSize->addItems({ "100","200","500" });
    m_pModel = new QStandardItemModel();
    QStringList headerListAction;		//水平表头
    headerListAction << A2T("索引") << A2T("测点名") << A2T("测点描述") <<A2T("值")<<A2T("质量")<<A2T("刷新时间")<< A2T("扫描频率(ms)") << A2T("读取权限") << A2T("数据类型") <<
        A2T("采集驱动类型") << A2T("采集驱动地址") << A2T("keyAddr") << A2T("死区") << A2T("例外报告");
    QList<quint16> listColumnWidth;		//列宽
    listColumnWidth << 50 << 250 << 350 << 100 << 100 << 250 << 100 << 100 << 100 << 150 << 150 << 100 << 100 << 100;
    QList<quint16> listColumnHidden;	//隐藏列
    //设置列数
    m_pModel->setColumnCount(headerListAction.count());
    //设置表头
    m_pModel->setHorizontalHeaderLabels(headerListAction);
    ui->tableView->setModel(m_pModel);
    //设置列宽
    for (int i = 0; i < listColumnWidth.count(); i++)
    {
        ui->tableView->setColumnWidth(i, listColumnWidth.at(i));
    }
    //隐藏列
    if (0 < listColumnHidden.count())
    {
        for (quint16 i = 0; i < listColumnHidden.count(); i++)
        {
            ui->tableView->hideColumn(listColumnHidden.at(i));
        }
    }
}

void CTagMobitorDlg::updatePageInfo()
{
    m_nTotalPages = (m_vecFilterTags.size() + m_nPageSize - 1) / m_nPageSize;
    m_nTotalPages = qMax(m_nTotalPages, 0); // 处理空数据情况
    ui->labelPage->setText(QString(A2T("第 %1 页 / 共 %2 页").arg(m_nCurrentPage).arg(m_nTotalPages)));
    updateButtonStates(); // 每次更新页面时同步按钮状态
}

void CTagMobitorDlg::updateButtonStates()
{
    const bool hasPrev = m_nCurrentPage > 1;
    const bool hasNext = m_nCurrentPage < m_nTotalPages;

    ui->pushButtonPre->setEnabled(hasPrev);
    ui->pushButtonNext->setEnabled(hasNext);
}

void CTagMobitorDlg::loadPointList()
{
    if (m_pModel == nullptr)
    {
        return;
    }
    //首先清空列表
    m_pModel->removeRows(0, m_pModel->rowCount());
    //刷新状态
    const int nStart = (m_nCurrentPage - 1) * m_nPageSize;
    const int nEnd = qMin(nStart + m_nPageSize, m_vecFilterTags.size());
    for (int i = nStart; i < nEnd; ++i)
    {
        CTagData* pTag = m_vecFilterTags.value(i);
        if (pTag == nullptr) continue;
        QList<QStandardItem*> rowItems;
        rowItems << new QStandardItem(QString::number(pTag->m_nIndex));
        rowItems << new QStandardItem(pTag->m_sTagName);
        rowItems << new QStandardItem(pTag->m_sTagDesc);
        switch (pTag->m_nDataType)
        {
        case CTagData::enUint8:
            rowItems << new QStandardItem(QString::number(pTag->value.byte));
            break;
        case CTagData::enInt16:
            rowItems << new QStandardItem(QString::number(pTag->value.un16Num));
            break;
        case CTagData::enUint16:
            rowItems << new QStandardItem(QString::number(pTag->value.n16Num));
            break;
        case CTagData::enInt32:
            rowItems << new QStandardItem(QString::number(pTag->value.n32Num));
            break;
        case CTagData::enUint32:
            rowItems << new QStandardItem(QString::number(pTag->value.un32Num));
            break;
        case CTagData::enInt64:
            rowItems << new QStandardItem(QString::number(pTag->value.n64Num));
            break;
        case CTagData::enUint64:
            rowItems << new QStandardItem(QString::number(pTag->value.un64Num));
            break;
        case CTagData::enFloat:
            rowItems << new QStandardItem(QString::number(pTag->value.fNum, 'f', 2));
            break;
        case CTagData::enDouble:
            rowItems << new QStandardItem(QString::number(pTag->value.dNum, 'f', 2));
            break;
        case CTagData::enString:
            rowItems << new QStandardItem(pTag->m_sValue);
            break;
        default:
            rowItems << new QStandardItem(A2T(""));
            break;
        }
        switch (pTag->m_nQuality)
        {
        case CTagData::Q_GOOD:
            rowItems << new QStandardItem(A2T("正常"));
            break;
        case CTagData::Q_SCANOFF:
            rowItems << new QStandardItem(A2T("强制"));
            break;
        case CTagData::Q_L3:
            rowItems << new QStandardItem(A2T("越下3限"));
            break;
        case CTagData::Q_LL:
            rowItems << new QStandardItem(A2T("越下下限"));
            break;
        case CTagData::Q_LO:
            rowItems << new QStandardItem(A2T("越下限"));
            break;
        case CTagData::Q_UP:
            rowItems << new QStandardItem(A2T("越上限"));
            break;
        case CTagData::Q_UU:
            rowItems << new QStandardItem(A2T("越上上限"));
            break;
        case CTagData::Q_U3:
            rowItems << new QStandardItem(A2T("越上3限"));
            break;
        case CTagData::Q_BAD:
            rowItems << new QStandardItem(A2T("异常"));
            break;
        case CTagData::Q_TIMEOUT:
            rowItems << new QStandardItem(A2T("超时"));
            break;
        case CTagData::Q_DATAERR:
            rowItems << new QStandardItem(A2T("数据错误/未读取数据"));
            break;
        case CTagData::Q_DRVERR:
            rowItems << new QStandardItem(A2T("驱动错误"));
            break;
        case CTagData::Q_ADDRERR:
            rowItems << new QStandardItem(A2T("地址错误"));
            break;
        case CTagData::Q_SVRERR:
            rowItems << new QStandardItem(A2T("服务错误"));
            break;
        case CTagData::Q_HWERR:
            rowItems << new QStandardItem(A2T("硬件故障"));
            break;
        case CTagData::Q_UNVALID:
            rowItems << new QStandardItem(A2T("无效数据"));
            break;
        case CTagData::Q_UNKOWN:
            rowItems << new QStandardItem(A2T("数据错误"));
            break;
        default:
            rowItems << new QStandardItem(A2T("其他 %1").arg(pTag->m_nQuality));
            break;
        }
        rowItems << new QStandardItem(QString::fromStdString(CTagData::getTimeString(pTag->m_nTimeStamp)));
        rowItems << new QStandardItem(QString::number(pTag->m_nScanRate));
        rowItems << new QStandardItem(pTag->m_sDataAccess);
        switch (pTag->m_nDataType)
        {
        case CTagData::enUint8:
            rowItems << new QStandardItem(A2T("Uint8"));
            break;
        case CTagData::enInt16:
            rowItems << new QStandardItem(A2T("Int16"));
            break;
        case CTagData::enUint16:
            rowItems << new QStandardItem(A2T("Uint16"));
            break;
        case CTagData::enInt32:
            rowItems << new QStandardItem(A2T("Int32"));
            break;
        case CTagData::enUint32:
            rowItems << new QStandardItem(A2T("Uint32"));
            break;
        case CTagData::enInt64:
            rowItems << new QStandardItem(A2T("Int64"));
            break;
        case CTagData::enUint64:
            rowItems << new QStandardItem(A2T("Uint64"));
            break;
        case CTagData::enFloat:
            rowItems << new QStandardItem(A2T("Float"));
            break;
        case CTagData::enDouble:
            rowItems << new QStandardItem(A2T("Double"));
            break;
        case CTagData::enString:
            rowItems << new QStandardItem(A2T("String"));
            break;
        default:
            rowItems << new QStandardItem(A2T("其他 %1").arg(pTag->m_nDataType));
            break;
        }
        rowItems << new QStandardItem(pTag->m_sCollectDrv);
        rowItems << new QStandardItem(pTag->m_sCollectAddr);
        rowItems << new QStandardItem(pTag->m_sKeyAddr);
        rowItems << new QStandardItem(QString::number(pTag->m_dDeadband));
        rowItems << new QStandardItem(pTag->m_nExceptionReport==0 ? A2T("否"):A2T("是"));
        for(auto item:rowItems)
        {
            item->setTextAlignment(Qt::AlignCenter);
        }
        m_pModel->appendRow(rowItems);
    }
    updatePageInfo();
}

void CTagMobitorDlg::setFilter(const QString &sFilterText)
{
    QMutexLocker(CPublicData::instance().m_pMutex);
    m_vecFilterTags.clear();
    // 遍历所有标签进行筛选
    for (CTagData* pTag : CPublicData::instance().m_vecTag)
    {
        if (sFilterText.isEmpty()|| sFilterText=="*" || pTag->m_sTagName.contains(sFilterText, Qt::CaseInsensitive))
        {
            m_vecFilterTags.append(pTag);
        }
    }
    // 重置分页到第一页
    m_nCurrentPage = 1;

    // 计算总页数
    m_nTotalPages = qMax(1, (m_vecFilterTags.size() + m_nPageSize - 1) / m_nPageSize);
}

void CTagMobitorDlg::slotComboBoxPageSizeChanged(const QString &sSize)
{
    m_nPageSize = sSize.toInt();
    m_nCurrentPage = 1; // 重置到第一页
    loadPointList();
}

void CTagMobitorDlg::slotPushButtonPre()
{
    if (m_nCurrentPage > 1)
    {
        m_nCurrentPage--;
        loadPointList();
    }
}

void CTagMobitorDlg::slotPushButtonNext()
{
    const int nTotalPages = (CPublicData::instance().m_vecTag.size() + m_nPageSize - 1) / m_nPageSize;
    if (m_nCurrentPage < nTotalPages)
    {
        m_nCurrentPage++;
        loadPointList();
    }
}

void CTagMobitorDlg::slotPushButtonJump()
{
    bool ok;
    int page = ui->lineEditPage->text().toInt(&ok);
    if (!ok || page < 1 || page >(CPublicData::instance().m_vecTag.size() + m_nPageSize - 1) / m_nPageSize)
    {
        messageBox(0,A2T("请输入有效页码"));
        return;
    }

    m_nCurrentPage = page;
    loadPointList();
}

void CTagMobitorDlg::slotDataFlush()
{
    if (CPublicData::instance().m_nClientTagReload == CPublicData::enTagReloading)
    {
        ui->labelHint->setText(A2T("点表更新操作中，请等待更新完成后再刷新数据"));
        return;
    }
    loadPointList();
}

void CTagMobitorDlg::slotPushButtonFilter()
{
    setFilter(ui->lineEditFilter->text().trimmed());
    loadPointList();
}
